#include "writepng.h"

int writepng_all(FILE *outfile, spng *png) {
    /* step 1: housekeeping */
    /* initialize libpng structure for output png */
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
        return ERR_MEMALLOC; // out of memory

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return ERR_MEMALLOC; // out of memory
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return ERR_WRITEPNG_INIT;
    }

    /* step 2: actual png writing */
    png_init_io(png_ptr, outfile);

    /* write header */
    if (setjmp(png_jmpbuf(png_ptr)))
        return ERR_WRITEPNG_HEADER;

    png_set_IHDR(
        png_ptr, info_ptr,
        png->width, png->height,
        png->bit_depth, png->color_type,
        PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE
    );

    png_write_info(png_ptr, info_ptr);

    /* write bytes */
    if (setjmp(png_jmpbuf(png_ptr)))
        return ERR_WRITEPNG_BODY;

    png_write_image(png_ptr, png->row_pointers);

    if (setjmp(png_jmpbuf(png_ptr)))
        return ERR_WRITEPNG_END;

    png_write_end(png_ptr, NULL);

    return 0;
}

void writepng_cleanup() {
    if (png_ptr && info_ptr) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        png_ptr  = NULL;
        info_ptr = NULL;
    }
}
